package cn.sxgan.gen.exception;

import cn.sxgan.gen.utils.Result;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.resource.NoResourceFoundException;

import java.io.IOException;

/**
 * @Description: 全局异常处理器
 * @Author: sxgan
 * @Date: 2024/3/1 15:07
 * @Version: 1.0
 **/
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    // 指定出现什么异常执行这个方法
    @ExceptionHandler(Exception.class)
    @ResponseBody // 为了返回数据
    public Result error(Exception e) {
        e.printStackTrace();
        log.error("GlobalExceptionHandler Exception e {}", ExceptionUtils.getMessage(e));
        return Result.fail(ExceptionUtils.getMessage(e));
    }
    
    // 特定异常
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody // 为了返回数据
    public Result error(ArithmeticException e) {
        e.printStackTrace();
        return Result.fail("执行了ArithmeticException异常处理..");
    }
    
    // 特定异常
    @ExceptionHandler(value = {IOException.class, HttpMessageNotWritableException.class})
    @ResponseBody // 为了返回数据
    public Result error(IOException e) {
        // e.printStackTrace();
        log.error("IO连接中断异常的特殊处理");
        return Result.fail("执行了IOException异常处理..");
    }
    
    // 自定义异常
    @ExceptionHandler(ApiException.class)
    @ResponseBody
    public Result<String> error(ApiException e) {
        log.error(ExceptionUtils.getMessage(e));
        e.printStackTrace();
        log.error("ApiException Exception e {}", ExceptionUtils.getMessage(e));
        return Result.fail(null, e.getCode(), e.getMessage());
    }
    
    /**
     * 校验异常
     *
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<String> handleValidationExceptions(
            MethodArgumentNotValidException ex) {
        
        StringBuilder errors = new StringBuilder();
        ex.getBindingResult().getFieldErrors().forEach(error -> {
            errors.append(error.getDefaultMessage());
            errors.append("！");
        });
        return Result.fail(errors.toString());
    }
    // 自定义异常
    // @ExceptionHandler(CardInterfaceException.class)
    // @ResponseBody
    // public Result error(CardInterfaceException e) {
    //     log.error(ExceptionUtil.getMessage(e));
    //     e.printStackTrace();
    //     return Result.fail(e.getMsg());
    // }
    
    @ExceptionHandler(NoResourceFoundException.class)
    public void handleResourceNotFound(NoResourceFoundException ex,
                                       HttpServletResponse response) {
        String path = ex.getResourcePath();
        
        // 只忽略特定路径的404
        if (path != null && (
                path.endsWith("js/axios.min.js.map") ||
                        path.contains(".well-known/appspecific")
        )) {
            response.setStatus(404); // 静默返回404
        } else {
            // 其他资源路径按默认处理
            response.setStatus(404);
        }
    }
    
}
